/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
// l16scrn.hpp - Linear screen driver for 16-bpp (65K color) operation.
//
// Author: Kenneth G. Maxwell
//
// Copyright (c) 2006 Swell Software, Inc.
//              All Rights Reserved.
//
// Unauthorized redistribution of this source code, in whole or part,
// without the express written permission of Swell Software
// is strictly prohibited.
//
// Notes:
//
//  This screen driver is intended for use with 256-color systems that support
//  a linear frame buffer. Example controllers include the SMOS 135xx series
//  and the MPC823.
//
//
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

#ifndef _L16SCREEN_
#define _L16SCREEN_


/*--------------------------------------------------------------------------*/
#define PlotPointView(x, y, c)  *(SCANLINESTART(y) + x) =  c;


/*--------------------------------------------------------------------------*/
// Useful macros for dealing with 16-bit colors
/*--------------------------------------------------------------------------*/
#define REDVAL565(_c)   (PEGUBYTE)(((_c) >> 11) & 0x1f)
#define REDVAL555(_c)   (PEGUBYTE)(((_c) >> 10) & 0x1f)
#define GREENVAL565(_c) (PEGUBYTE)(((_c) >> 5) & 0x3f)
#define GREENVAL555(_c) (PEGUBYTE)(((_c) >> 5) & 0x1f)
#define BLUEVAL565(_c)  (PEGUBYTE)(((_c) ) & 0x1f)
#define BLUEVAL555(_c)  (PEGUBYTE)(((_c) ) & 0x1f)
#define REDVAL565_32(_c)     ((REDVAL565((_c) >> 16) << 16) | \
                               REDVAL565((_c) & 0xffff))
#define REDVAL555_32(_c)     ((REDVAL555((_c) >> 16) << 16) | \
                               REDVAL555((_c) & 0xffff))
#define GREENVAL565_32(_c)   ((GREENVAL565((_c) >> 16) << 16) | \
                               GREENVAL565((_c) & 0xffff))
#define GREENVAL555_32(_c)   ((GREENVAL555((_c) >> 16) << 16) | \
                               GREENVAL555((_c) & 0xffff))
#define BLUEVAL565_32(_c)    ((BLUEVAL565((_c) >> 16) << 16) | \
                               BLUEVAL565((_c) & 0xffff))
#define BLUEVAL555_32(_c)    ((BLUEVAL555((_c) >> 16) << 16) | \
                               BLUEVAL555((_c) & 0xffff))

#define MAKE565(r, g, b) ((((r) & 0x1f) << 11) | \
                          (((g) & 0x3f) << 5) | \
                          (((b) & 0x1f) ))
#define MAKE555(r, g, b) ((((r) & 0x1f) << 10) | \
                          (((g) & 0x1f) << 5) | \
                          (((b) & 0x1f) ))

#define MAKE565_32(r, g, b) (((r) << 11) | ((g) << 5) | (b))
#define MAKE555_32(r, g, b) (((r) << 10) | ((g) << 5) | (b))

#define BLEND2(c1, c2, a) ((((c1) * (a)) + (((c2) * (256 - (a))))) >> 8)

#define BLEND(_pt, _gr, _gg, _gb, _pr, _pg, _pb, _a, _na)           \
    {                                                               \
        (_pr) = (((_gr) * (_a)) + ((_pr) * (_na))) >> 8;            \
        (_pg) = (((_gg) * (_a)) + ((_pg) * (_na))) >> 8;            \
        (_pb) = (((_gb) * (_a)) + ((_pb) * (_na))) >> 8;            \
        *(_pt) = MAKEHICOLOR((_pr), (_pg), (_pb));                  \
    }

#define BLEND32(_pt, _gr, _gg, _gb, _pr, _pg, _pb, _a, _na)         \
    {                                                               \
        (_pr) = ((((_gr) * (_a)) + ((_pr) * (_na))) >> 8) & RBCONST;\
        (_pg) = ((((_gg) * (_a)) + ((_pg) * (_na))) >> 8) & GCONST; \
        (_pb) = ((((_gb) * (_a)) + ((_pb) * (_na))) >> 8) & RBCONST;\
        *(_pt) = MAKEHICOLOR_32((_pr), (_pg), (_pb));               \
    }

#define GETRGB565(_c, _r, _g, _b)       \
    {                                   \
        (_r) = REDVAL565(_c);           \
        (_g) = GREENVAL565(_c);         \
        (_b) = BLUEVAL565(_c);          \
    }

#define GETRGB555(_c, _r, _g, _b)       \
    {                                   \
        (_r) = REDVAL555(_c);           \
        (_g) = GREENVAL555(_c);         \
        (_b) = BLUEVAL555(_c);          \
    }

#define GETRGB565_32(_c, _r, _g, _b)    \
    {                                   \
        (_r) = REDVAL565_32(_c);        \
        (_g) = GREENVAL565_32(_c);      \
        (_b) = BLUEVAL565_32(_c);       \
    }

#define GETRGB555_32(_c, _r, _g, _b)    \
    {                                   \
        (_r) = REDVAL555_32(_c);        \
        (_g) = GREENVAL555_32(_c);      \
        (_b) = BLUEVAL555_32(_c);       \
    }

#ifdef PEG_RGB_USE_565
 #define REDVAL(_c)      REDVAL565(_c)
 #define GREENVAL(_c)    GREENVAL565(_c)
 #define BLUEVAL(_c)     BLUEVAL565(_c)
 #define REDVAL32(_c)    REDVAL565_32(_c)
 #define GREENVAL32(_c)  GREENVAL565_32(_c)
 #define BLUEVAL32(_c)   BLUEVAL565_32(_c)
 #define MAKEHICOLOR(r, g, b) MAKE565(r, g, b)
 #define MAKEHICOLOR_32(r, g, b) MAKE565_32(r, g, b)
 #define GETRGB(_c, _r, _g, _b) GETRGB565((_c), (_r), (_g), (_b))
 #define GETRGB32(_c, _r, _g, _b) GETRGB565_32((_c), (_r), (_g), (_b))
 #define RBCONST 0x001f001f
 #define GCONST  0x003f003f
#else
 #define REDVAL(_c)      REDVAL555(_c)
 #define GREENVAL(_c)    GREENVAL555(_c)
 #define BLUEVAL(_c)     BLUEVAL555(_c)
 #define REDVAL32(_c)    REDVAL555_32(_c)
 #define GREENVAL32(_c)  GREENVAL555_32(_c)
 #define BLUEVAL32(_c)   BLUEVAL555_32(_c)
 #define MAKEHICOLOR(r, g, b) MAKE555(r, g, b)
 #define MAKEHICOLOR_32(r, g, b) MAKE555_32(r, g, b)
 #define GETRGB(_c, _r, _g, _b) GETRGB555((_c), (_r), (_g), (_b))
 #define GETRGB32(_c, _r, _g, _b) GETRGB555_32((_c), (_r), (_g), (_b))
 #define RBCONST 0x001f001f
 #define GCONST  0x001f001f
#endif


/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
class L16Screen : public PegScreen
{
    public:
        L16Screen(const PegRect &);
        virtual ~L16Screen();

        virtual void Capture(PegCapture *Info, PegRect &Rect);

        virtual PegBitmap *CreateBitmap(PEGINT Width, PEGINT Height,
            PEGINT Style = BMF_RAW|BMF_HAS_TRANS);

        virtual PEGUBYTE *GetPalette(PEGULONG *pPutSize);

       #ifdef PEG_IMAGE_SCALING

        virtual PEGCOLOR GetBitmapPixel(PEGINT x, PEGINT y, PegBitmap *pMap)
        {
            PEGCOLOR *pGet = (PEGCOLOR *)pMap->pStart;
            pGet += pMap->Width * y;
            pGet += x;
            return *pGet;
        }

       #endif

        virtual PEGCOLOR GetPixelView(PEGINT x, PEGINT y)
        {
            if (mpContext)
            {
                return((PEGCOLOR) *(SCANLINESTART(y) + x));
            }
            else
            {
                return 0;
            }
        }

       #ifdef PEG_IMAGE_SCALING

        virtual void PutBitmapPixel(PEGINT x, PEGINT y, PegBitmap *pMap,
                                    PEGCOLOR Val)
        {
            PEGCOLOR *pPut = (PEGCOLOR *)pMap->pStart;
            pPut += pMap->Width * y;
            pPut += x;
            *pPut = Val;
        }

       #endif

        virtual void ResetPalette(void);
        virtual void SetPalette(PEGINT First, PEGINT Num,
                                const PEGUBYTE *pGet);

    protected:

       #ifdef PEG_AA_LINE
        virtual void AALineView(PEGINT xStart, PEGINT yStart, PEGINT xEnd,
                                PEGINT yEnd, const PegRect & View,
                                PegBrush &Brush);
       #endif

        virtual void BitmapView(const PegPoint Where,
                                const PegBitmap *pGetmap,
                                const PegRect &View);

        void Blend(PEGCOLOR *pGet, PEGCOLOR *pPut, PEGUINT Alpha,
                      PEGUINT Len);
        void Blend32(PEGULONG *pGet, PEGULONG *pPut, PEGUINT Alpha,
                         PEGUINT Len);
        PEGCOLOR BlendColor(PEGCOLOR gt, PEGCOLOR pt, PEGUINT Alpha,
                      PEGUINT NotAlpha);
        void BlendPerPix(PEGCOLOR *pGet, PEGCOLOR *pPut, PEGUINT Len);

       #if defined(PEG_MULT_SOFT_SURFACES)

        void BlendSurface(DrawSurface *pSurface, PegRect &Copy,
            PEGUBYTE *pComposite);

        PEGBOOL BuildCompositeSurface(PegRect &Copy, PEGUBYTE *pComposite);

        void CopySurface(DrawSurface *pSurface, PegRect &Copy,
            PEGUBYTE *pComposite);

       #endif

        void Draw8BitBitmap(const PegPoint Where, const PegRect &View,
            const PegBitmap *pGetmap);

       #ifdef PEG_AA_FONT
        virtual void DrawSimpleAliasedText(PegPoint Where,
                        const PEGCHAR *pText, PegBrush &Brush,
                        const PegFont *pFont, PEGINT Count, PegRect &Rect);

       #if defined(PEG_TRUE_ALIAS)

        virtual void DrawTrueAliasedText(PegPoint Where,
                        const PEGCHAR *pText, PegBrush &Brush,
                        const PegFont *pFont, PEGINT Count, PegRect &Rect);

        virtual void DrawAliasedTextToAlphaMap(PegPoint Where,
                        const PEGCHAR *pText, PegBrush &Brush,
                        const PegFont *pFont, PEGINT Count, PegRect &Rect);
       #endif
       #endif

       #ifdef PEG_PRO
        virtual void DrawAliasMapView(PegPoint Where, const PegBitmap *pMap,
            PegBrush &Brush, const PegRect &View);
       #endif

       #ifdef PEG_OUTLINE_FONT
        virtual void DrawOutlineText(PegPoint Where, const PEGCHAR *pText,
                                     PegBrush &Brush, const PegFont *pFont,
                                     PEGINT Count, PegRect &Rect);
       #endif

       #ifdef PEG_FREETYPE_SUPPORT
        virtual void DrawFreetypeAliasedText(PegPoint Where, const PEGCHAR *pText,
            PegBrush &Brush, const PegFont *pFont, PEGINT Count, PegRect &Clip);

        virtual void DrawFreetypeBinaryText(PegPoint Where, const PEGCHAR *pText,
            PegBrush &Brush, const PegFont *pFont, PEGINT Count, PegRect &Clip);
       #endif

        virtual void DrawRleBitmap(const PegPoint Where, const PegRect &View,
                                   const PegBitmap *pGetmap);

        void Draw8BitRleBitmap(const PegPoint Where, const PegRect &View,
            const PegBitmap *pGetMap);

        virtual void DrawTextView(PegPoint Where, const PEGCHAR *pText,
                                  PegBrush &Brush, const PegFont *pFont,
                                  PEGINT Count, PegRect &Rect);

        virtual PEGUBYTE *GetVideoAddress(void);
        virtual void HorizontalLine(PEGINT XStart, PEGINT XEnd, PEGINT YPos,
                                    PEGCOLOR Color, PEGINT Width);
        virtual void HorizontalLineXOR(PEGINT XStart, PEGINT XEnd,
                                       PEGINT YPos);
       #ifdef PEG_BIDI_SUPPORT
        virtual PEGINT LatinTextLength(PEGCHAR *pText);
       #endif
        virtual void LineView(PEGINT xStart, PEGINT yStart, PEGINT xEnd,
                              PEGINT yEnd, PegRect &Rect, PegBrush &Brush);

        void MakeAAColors(PEGCOLOR *PutColors, PegBrush &Brush);

        virtual void PlotSubPixel(PegFixed xVal, PegFixed yVal,
                                  PEGCOLOR Color);

        virtual void RectMoveView(const PegRect &View,
                                  const PEGINT xMove, const PEGINT yMove);

       #ifdef PEG_PRO
       #ifdef PEG_AA_LINE
        virtual void TrueAliasLineView(PEGINT xStart, PEGINT yStart, PEGINT xEnd,
                                PEGINT yEnd, const PegRect &View,
                                PegBrush &Brush);
       #endif
       #endif // PEG_PRO

        virtual void VerticalLine(PEGINT YStart, PEGINT YEnd, PEGINT XPos,
                                  PEGCOLOR Color, PEGINT Width);
        virtual void VerticalLineXOR(PEGINT YStart, PEGINT YEnd, PEGINT XPos);

        PEGCOLOR mHiPalette[256];

};

#endif



